﻿/*
 * msgparas.hpp
 *
 *  Created on: 2017年3月17日
 *      Author: work
 */

#ifndef _DM_MSG_TYPES_HPP_
#define _DM_MSG_TYPES_HPP_

#include <dm/export.hpp>

#ifndef DM_API_OS_MSG
#define DM_API_OS_MSG DM_API_IMPORT
#endif

#include <dm/types.hpp>
#include <dm/timestamp.hpp>
#include <dm/scada/types.hpp>

namespace dm{
namespace msg{

typedef dm::scada::index_t index_t;

/**
 * 消息类型
 */
enum DM_API_OS_MSG EMsgType{
	Msg_Test = 0,	//!< 未定义
	Msg_SyncClock,	//!< 系统对时 无参数
	Msg_Call,			//!< 召唤
	Msg_RemoteCtl,	//!< 远控
	Msg_Set,			//!< 参数设置
	Msg_Get,			//!< 参数读取
	Msg_Update,		//!< 参数更新

	Msg_SyncData,	//!< 同步远端数据
	Msg_RemoteReset,//!< 远端复位

	Msg_Max
};

DM_API_OS_MSG const char* msgTypeString( const EMsgType& type );

/**
 * 消息应答标志
 */
enum DM_API_OS_MSG EMsgAck{
	MaNoAck,	//!< 发送无应答
	MaAck,		//!< 发送必须应答
	MaSuccess,	//!< 应答成功
	MaPart,		//!< 应答部分成功
	MaFail,		//!< 应答失败
	MaTimeout,	//!< 应答超时
	MaDeny,		//!< 应答拒绝执行
	MaBusy,		//!< 应答繁忙
	MaParas,	//!< 应答参数错误
	MaIndex,	//!< 应答索引错误
	MaMax
};

DM_API_OS_MSG const char* msgAckString( const EMsgAck& ack );

/**
 * 召唤参数
 */
struct DM_API_OS_MSG SCallInfo{
	typedef dm::uint16 group_t;
	group_t group;
}PACKED_SUF;

/**
 * 遥控标志
 */
enum DM_API_OS_MSG ERemoteControl{
	Rc_None,    //!< Rc_None 无
	Rc_PreOpen, //!< Rc_PreOpen 预控分
	Rc_PreClose,//!< Rc_PreClose 预控合
	Rc_Open,    //!< Rc_Open 控分
	Rc_Close,   //!< Rc_Close 空合
	Rc_Cancel   //!< Rc_Cancel 取消
};

DM_API_OS_MSG const char* msgRemoteCtlString( const ERemoteControl& ctl );

/**
 * 远控信息
 */
struct DM_API_OS_MSG SRemoteCtlInfo{
	index_t		   device;
	index_t 	   index;
	ERemoteControl remoteCtl;
} PACKED_SUF;

/**
 * 参数信息
 */
struct DM_API_OS_MSG SParaInfo{
	index_t device;
	index_t index;
	index_t num;
} PACKED_SUF;

/**
 * 参数命令参数
 */
struct DM_API_OS_MSG SParaData{
	enum{
		MaxLen = 512
	};

	/**
	 * 参数类型
	 */
	enum EDataType{
		DtBinary = 0,//!< 二进制
		DtInt8,      //!< int8
		DtUint8,     //!< uint8
		DtInt16,     //!< int16
		DtUint16,    //!< uint16
		DtInt32,     //!< int32
		DtUint32,    //!< uint32
		DtInt64,     //!< int64
		DtUint64,    //!< uint64
		DtFloat32,   //!< float32
		DtFloat64,   //!< float64
		DtString     //!< string
	};

	index_t device;
	index_t index;
	index_t num;
	EDataType type;

	union{
		dm::uint8 d_u8[MaxLen];
		dm::int8  d_i8[MaxLen];
		dm::uint16 d_u16[MaxLen/2];
		dm::int16  d_i16[MaxLen/2];
		dm::uint32 d_u32[MaxLen/4];
		dm::int32  d_i32[MaxLen/4];
		dm::uint64 d_u64[MaxLen/8];
		dm::int64  d_i64[MaxLen/8];

		dm::float32 d_f32[MaxLen/4];
		dm::float64 d_f64[MaxLen/8];
	}data;

	size_t dataLen()const;

	void clone( const SParaData& pd );

	static const char* typeString( const EDataType& type );

	static inline int maxNum_binary(){
		return MaxLen;
	}

	static inline int maxNum_int8(){
		return MaxLen;
	}

	static inline int maxNum_uint8(){
		return maxNum_int8();
	}

	static inline int maxNum_int16(){
		return MaxLen/2;
	}

	static inline int maxNum_uint16(){
		return MaxLen/2;
	}

	static inline int maxNum_int32(){
		return MaxLen/4;
	}

	static inline int maxNum_uint32(){
		return MaxLen/4;
	}

	static inline int maxNum_int64(){
		return MaxLen/4;
	}

	static inline int maxNum_uint64(){
		return MaxLen/8;
	}

	static inline int maxNum_float32(){
		return MaxLen/4;
	}

	static inline int maxNum_float64(){
		return MaxLen/8;
	}

	static inline int maxNum_string(){
		return MaxLen - 1;
	}

	inline const dm::uint8* as_binary()const{
		return data.d_u8;
	}

	inline dm::uint8* as_binary(){
		return data.d_u8;
	}

	inline const dm::int8* as_int8()const{
		return data.d_i8;
	}

	inline dm::int8* as_int8(){
		return data.d_i8;
	}

	inline const dm::uint8* as_uint8()const{
		return data.d_u8;
	}

	inline dm::uint8* as_uint8(){
		return data.d_u8;
	}

	inline const dm::int16* as_int16()const{
		return data.d_i16;
	}

	inline dm::int16* as_int16(){
		return data.d_i16;
	}

	inline const dm::uint16* as_uint16()const{
		return data.d_u16;
	}

	inline dm::uint16* as_uint16(){
		return data.d_u16;
	}

	inline const dm::int32* as_int32()const{
		return data.d_i32;
	}

	inline dm::int32* as_int32(){
		return data.d_i32;
	}

	inline const dm::uint32* as_uint32()const{
		return data.d_u32;
	}

	inline dm::uint32* as_uint32(){
		return data.d_u32;
	}

	inline const dm::int64* as_int64()const{
		return data.d_i64;
	}

	inline dm::int64* as_int64(){
		return data.d_i64;
	}

	inline const dm::uint64* as_uint64()const{
		return data.d_u64;
	}

	inline dm::uint64* as_uint64(){
		return data.d_u64;
	}

	inline const dm::float32* as_float32()const{
		return data.d_f32;
	}

	inline dm::float32* as_float32(){
		return data.d_f32;
	}

	inline const dm::float64* as_float64()const{
		return data.d_f64;
	}

	inline dm::float64* as_float64(){
		return data.d_f64;
	}

	inline const char* as_string()const{
		return data.d_i8;
	}

	inline char* as_string(){
		return data.d_i8;
	}

	inline const char* getTypeString()const{
		return typeString(type);
	}
}PACKED_SUF;

/**
 * 同步的数据类型
 */
enum DM_API_OS_MSG ESyncDataType{
	SDT_None = 0,	//!< 不同步
	SDT_Status,		//!< 同步状态量
	SDT_Discrete,	//!< 同步离散量
	SDT_Measure,	//!< 同步测量量
	SDT_Cumulant,	//!< 同步累计量
	SDT_All			//!< 同步所有
};

DM_API_OS_MSG const char* msgSyncTypeString( const ESyncDataType& type );

struct DM_API_OS_MSG SSyncInfo{
	ESyncDataType type;
}PACKED_SUF;

}
}

#endif /* INCLUDE_DM_MSGPARAS_HPP_ */
